/**
 * 创建一个自定义钩子以管理浏览器的历史记录
 * 这个钩子提供了订阅URL变化、获取当前URL快照、以及推送和替换URL的能力
 *
 * @returns 返回一个元组，包含当前URL的快照、推送新URL的函数和替换当前URL的函数
 */
export const useHistory = () => {
  /**
   * 订阅URL变化事件
   * 当浏览器的URL通过前进、后退或直接地址栏访问时触发
   *
   * @param callback 回调函数，用于处理URL变化事件
   * @returns 返回一个函数，用于取消订阅URL变化事件
   */
  const subscribe = (callback: () => void) => {
    window.addEventListener('popstate', callback);
    window.addEventListener('hashchange', callback);
    return () => {
      window.removeEventListener('hashchange', callback);
      window.removeEventListener('popstate', callback);
    };
  };

  /**
   * 获取当前URL的快照
   *
   * @returns 返回当前的URL字符串
   */
  const getSnapshot = () => {
    return window.location.href;
  };

  /**
   * 推送一个新的URL到浏览器的历史记录堆栈中
   * 这个操作会在不刷新页面的情况下改变URL
   *
   * @param path 新的URL路径
   */
  const push = (path: string) => {
    window.history.pushState(null, '', path);
    window.dispatchEvent(new PopStateEvent('popstate'));
  };

  /**
   * 替换当前的URL在浏览器的历史记录中
   * 这个操作会在不刷新页面的情况下改变URL
   *
   * @param path 新的URL路径
   */
  const replace = (path: string) => {
    window.history.replaceState(null, '', path);
    window.dispatchEvent(new PopStateEvent('popstate'));
  };

  // 使用外部存储同步钩子来同步浏览器历史状态
  const res = useSyncExternalStore(subscribe, getSnapshot);
  // 返回当前URL的快照、推送新URL的函数和替换当前URL的函数
  return [res, push, replace] as const;
};
